﻿// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using MyApplication;
using MyApplication.Dtos;
using MyEFCore;
using MyWebApi.Infrostructure;
using MyWebApi.Models;

namespace MyWebApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private readonly ILogger<ProductsController> _logger;
        private readonly IProductService _productService;
        private readonly IRepositoryManager _repositoryManager;
        private readonly IMapper _mapper;
        private readonly PageOptions _pageOptions;

        public ProductsController(ILogger<ProductsController> logger,
            IProductService productService,
            IRepositoryManager repositoryManager,
            IMapper mapper, IOptions<PageOptions> pageOptions)
        {
            _logger = logger;
            _productService = productService;
            _repositoryManager = repositoryManager;
            _mapper = mapper;
            _pageOptions = pageOptions.Value;
        }

        [HttpGet]
        public async Task<IActionResult> GetAllProducts([FromQuery] PageOptions pageOptions)
        {
            _logger.LogDebug("Get all products with paged list");
            NormalizePageOptions(pageOptions);
            var query = await _productService.GetAllPrpoductsAsync();
            var products = PagedList<Product>.ToPagedList(query.OrderBy(x => x.ProductId),
                pageOptions.PageNumber.Value, pageOptions.PageSize.Value);
            WritePagedListToHeader(products);
            return Ok(_mapper.Map<List<ProductDto>>(products));
        }

        private void WritePagedListToHeader<T>(PagedList<T> pagedList)
        {
            Response.Headers.Add("X-Pagination", pagedList.MetaData.ToJson());
        }

        private void NormalizePageOptions(PageOptions pageOptions)
        {
            pageOptions.PageSize ??= _pageOptions.PageSize;
            pageOptions.PageNumber ??= _pageOptions.PageNumber;
        }

        [HttpGet]
        [Route("{id}", Name = "GetProductById")]
        public async Task<ActionResult<ProductDto>> GetProductById(int id)
        {
            var dto = await _productService.GetProductByIdAsync(id);
            if (dto == null) return NotFound();
            return dto;
        }

        [HttpPost]
        public async Task<IActionResult> Post(CreateProductDto productDto)
        {
            var id = await _productService.CreateNewProductAsync(productDto);
            return CreatedAtRoute("GetProductById", new { Id = id }, new { ProductId = id });
        }

        [HttpPut]
        [Route("{id}")]
        public async Task<IActionResult> Put(int id, UpdateProductDto dto)
        {
            await _productService.UpdateProductAsync(id, dto);
            return Ok();
        }

        [HttpDelete]
        [Route("{id}")]
        public async Task<IActionResult> Delete(int id)
        {
            await _productService.DeleteProductAsync(id);
            return Ok();
        }
    }
}
